package com.katesoft.scale4j.web.model;

import com.katesoft.scale4j.persistent.model.unified.AbstractPersistentEntity;
import com.katesoft.scale4j.web.security.ISecurityRoles;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.envers.Audited;
import org.springframework.core.Constants;
import org.springframework.security.core.GrantedAuthority;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Classical implementation of Role entity.
 *
 * @author kate2007
 */
@SuppressWarnings("serial")
@Entity
@Audited
@Table(name = "t_role")
@org.hibernate.annotations.Entity(dynamicUpdate = true, mutable = true)
@Access(AccessType.FIELD)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NamedQueries(value = {@NamedQuery(name = Role.QUERY_FIND_BY_ROLE,
                                   query = "select r from Role r where r." + Role.PROP_ROLE + " = :username")})
public class Role extends AbstractPersistentEntity implements ISecurityRoles, GrantedAuthority
{
    // queries
    public static final String QUERY_FIND_BY_ROLE = "role.find_by_role";
    // properties
    public static final String PROP_ROLE = "role";
    public static final String PROP_DESCRIPTION = "description";
    // ***********************************************************************
    // ************************ persistent fields ****************************
    // ***********************************************************************
    @Column(name = "role", nullable = false, length = 100)
    private String role;
    @Column(name = "description", length = 2000)
    private String description;
    // ***********************************************************************
    // ************************* (getters+setters) ***************************
    // ***********************************************************************

    public Role()
    {
        super();
    }

    public Role(String role)
    {
        this.role = role;
    }

    public String getRole()
    {
        return role;
    }

    public void setRole(final String role)
    {
        this.role = role;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(final String description)
    {
        this.description = description;
    }

    @Transient
    @Override
    /**
     * spring security authority field.
     */
    public String getAuthority()
    {
        return getRole();
    }

    public static Collection<String> supportedRoles()
    {
        Collection<String> roles = new HashSet<String>();
        Constants constants = new Constants(ISecurityRoles.class);
        Set<Object> values = constants.getValues("ROLE");
        for (Object object : values) {
            if (object instanceof String) {
                roles.add((String) object);
            }
        }
        return roles;
    }
}
